<template>
  <div class="paginate-table">
    <el-table ref="elTable" v-loading="loading" :row-class-name="rowClassName" :data="data" :header-cell-style="{
      background: 'rgba(132, 138, 174, 0.06)',
    }" :stripe="stripe" :border="border" :row-key="rowKey" :tree-props="treeProps"
      :highlight-current-row="highlightCurrentRow" :max-height="maxTableHeight" @expand-change="expandChange"
      @selection-change="handleSelectionChange" @current-change="handleTableCurrentChange" @select="handleSelect"
      @select-all="handleSelectAll" @row-click="handleRowClick">
      <slot></slot>
    </el-table>
    <div v-if="showPager" class="page">
      <el-pagination v-model:currentPage="pager.currentPage" v-model:pageSize="pager.showCount"
        :page-sizes="pager.pageSizes" background layout="total, sizes, prev, pager, next, jumper"
        :total="pager.totalResult" @size-change="handleSizeChange" @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    <slot name="pagination"></slot>
  </div>
</template>

<script>
import { request } from "@/utils/request";
export default defineComponent({
  name: "LayoutTable",
  props: {
    rowKey: {
      require: false,
      type: [String, Function],
      default: () => {
        return "";
      },
    },
    treeProps: {
      require: false,
      type: Object,
      default: () => {
        return {};
      },
    },
    border: {
      require: false,
      type: Boolean,
      default: () => {
        return false;
      },
    },
    highlightCurrentRow: {
      // 点击后高亮
      require: false,
      type: Boolean,
      default: () => {
        return false;
      },
    },
    stripe: {
      require: false,
      type: Boolean,
      default: () => {
        return true;
      },
    },
    listColumName: {
      require: false,
      type: String,
      default: "",
    },
    param: {
      require: false,
      type: Object,
      default: () => {
        return {};
      },
    },
    debounce: {
      require: false,
      type: Number,
      default: 500,
    },
    url: {
      require: false,
      type: String,
      default: "",
    },
    hideInit: {
      require: false,
      type: Boolean,
      default: false,
    },
    hideWatch: {
      require: false,
      type: Boolean,
      default: false,
    },
    showPager: {
      require: false,
      type: Boolean,
      default: true,
    },
    noPage: {
      // 是否为不分页
      require: false,
      type: Boolean,
      default: false,
    },
    singleData: {
      // 是否为单条非数组数据
      require: false,
      type: Boolean,
      default: false,
    },
    // eslint-disable-next-line vue/require-default-prop
    filter: {
      type: Function,
      require: false,
    },
    disableAutoHeight: {
      require: false,
      type: Boolean,
      default: false,
    },
    rowClassName: {
      type: [Function, String],
      require: false,
      default: "",
    },
    dataList: {
      type: Array,
      require: false,
      default: () => {
        return [];
      },
    },
    isLoading: {
      // 是否显示loading效果
      type: Boolean,
      default: true,
    },
    showCount: {
      // 每页多少条数据
      type: Number,
      default: 15,
    },
    setSearch: {
      // 调用查询search()
      type: Number,
      default: null,
    },
    total: {
      type: Number,
      default: 0,
    },
    currentPage: {
      type: Number,
      default: 0,
    },


  },
  data() {
    return {
      tableData: [], // 所有列表
      maxTableHeight: undefined,
      loading: false,
      list: [],
      isPager: false,
      pager: {
        currentPage: 1,
        showCount: 10,
        pageSizes: [10, 20, 40],
        totalResult: 0,
      },
      autoSearchInd: null,
    };
  },
  computed: {
    data() {
      if (this.filter) {
        return this.filter(this.list);
      }
      return this.list;
    },
  },
  watch: {
    data: {
      deep: true,
      handler() {
        this.autoHeight();
      },
    },
    url: {
      deep: false,
      handler() {
        this.research();
      },
    },
    currentPage: {
      deep: false,
      handler(val) {
        this.pager.totalResult = this.total;
        this.pager.currentPage = val
      },
    },
    param: {
      deep: true,
      handler() {
        if (!this.hideWatch && !this.total) {
          if (this.autoSearchInd) {
            clearTimeout(this.autoSearchInd);
          }
          this.autoSearchInd = setTimeout(this.research, this.debounce);
        }
      },
    },
    setSearch(val) {
      this.search();
    },
  },
  created() {
    if (this.showPager) {
      this.isPager = true;
      // let size = this.size || 15
      // let pageSizes = [15, 30, 50]
      // if (this.size===10) {
      //   pageSizes = [10, 20, 40]
      // }

      // this.pager = {
      //   currentPage: 1,
      //   size,
      //   pageSizes
      // }
    } else {
      this.isPager = false;
    }
    this.setStoragePage();
    window.addEventListener("resize", this.autoHeight);
    if (!this.hideInit) {
      this.search();
    }
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.autoHeight);
  },
  methods: {
    autoHeight() {
      if (this.disableAutoHeight) {
        return;
      }
      this.$nextTick(() => {
        let pageEl = document.querySelector("main.el-main");
        if (!pageEl) return;
        let pageHeight = pageEl.clientHeight;
        let tableEl = this.$el.querySelector(".el-table");
        let tablePosition = tableEl.getBoundingClientRect();
        let differentHeight = pageHeight - tablePosition.top;
        if (differentHeight > 0) {
          this.maxTableHeight = differentHeight;
        }
      });
    },
    handleSizeChange(s) {
      this.pager.showCount = s;
      this.search();
      this.$emit("handleSizeChange", s);
    },
    handleCurrentChange(page) {
      this.pager.currentPage = page;
      this.search();
      this.$emit("handleCurrentChange", page);
    },
    deleteRow(row) {
      let ind = this.list.indexOf(row);
      if (ind > -1) {
        this.list.splice(ind, 1);
      }
    },
    addRow(row) {
      this.list.push(row);
    },
    async research() {
      if (this.isPager) {
        this.pager.currentPage = 1;
      }
      this.search();
    },
    // 计算属性对数据进行处理
    frontEndPageChange() {
      let start = (this.pager.currentPage - 1) * this.pager.showCount;
      if (start >= this.tableData.length) start = 0;
      let end = this.pager.currentPage * this.pager.showCount;
      if (end >= this.tableData.length) end = this.tableData.length;
      this.list = this.tableData.slice(start, end);
    },
    async search() {
      if (!this.url) {
        this.tableData = this.dataList || [];
        this.frontEndPageChange();
        this.pager.totalResult = this.total || this.tableData.length;
        return;
      }
      this.loading = this.isLoading;
      let form = Object.assign({}, this.param || {}, {
        currentPage: this.pager.currentPage,
        showCount: this.pager.showCount,
      });
      let rs = await request(this.url, form);
      if (rs.code === 200) {
        let list = [];
        if (this.noPage) {
          list = rs.payload ?? [];
          if (this.singleData) {
            list = [rs.payload];
          }
        } else {
          list = this.listColumName
            ? rs.payload[this.listColumName]
            : rs.payload ?? [];
        }
        // 添加loading属性
        // list && list.forEach((item) => {
        //   let originData = Object.assign({}, item);
        //   item.originData = originData;
        //   item.loading = false;
        // });

        this.list = list;
        if (this.showPager) {
          this.pager.currentPage = rs.page.currentPage || 1;
          this.pager.showCount = rs.page.showCount || 30;
          this.pager.totalResult = rs.page.totalResult || 0;
        }
      }
      this.loading = false;
      this.$emit("loaded", this.list, rs);
    },

    expandChange(row, expandedRows) {
      this.$emit("expand-change", row, expandedRows);
    },
    handleSelectionChange(val) {
      this.$emit("selection-change", val);
    },
    handleTableCurrentChange(val) {
      this.$emit("current-change", val);
    },
    handleSelect(selection, row) {
      this.$emit("select", selection, row);
    },
    handleSelectAll(selection) {
      this.$emit("select-all", selection);
    },
    handleRowClick(val) {
      this.$emit("row-click", val);
    },
    setStoragePage() {
      var storage = window.localStorage;
      var currentPage = storage.getItem("channelPage");
      if (currentPage) {
        this.pager.current = parseInt(currentPage);
        storage.removeItem("channelPage");
      }
    },
    toggleRowSelection(row, selected) {
      if (this.$refs.elTable) {
        if (selected === undefined) this.$refs.elTable.toggleRowSelection(row);
        else {
          this.$refs.elTable.toggleRowSelection(row, selected);
        }
      }
    },

    clearSelection() {
      this.$refs.elTable.clearSelection()
    }
  },
});
</script>

<style scoped lang="scss">
.paginate-table {

  // overflow: auto;
  :deep(.el-table) {
    // width: 99% !important;
    font-size: 14px;
    margin-bottom: 10px;

    th {
      height: 53px;
    }
  }
}

.paginate-pager {
  padding: 10px 0;
}

:deep(.el-pagination) {

  span,
  button,
  .el-pager,
  li,
  input,
  .el-input {
    font-size: 14px;
    line-height: 32px;
    height: 32px;
  }
}

:deep(.el-checkbox__inner) {
  border: 1px solid #eaeaea;
}
</style>
